package com.wxy.demo.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.wxy.demo.core.*;
import com.wxy.demo.dao.DataSourceInfoDao;
import com.wxy.demo.dao.InterfaceInfoDao;
import com.wxy.demo.dto.SendDto;
import com.wxy.demo.dto.SendTestDto;
import com.wxy.demo.entity.DataSourceInfo;
import com.wxy.demo.entity.InterfaceInfo;
import com.wxy.demo.util.DbUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;

/**
 * <p>
 *
 * </p>
 *
 * @author e-Xiaoyuan.Wang
 * @since 2022/1/14 10:14
 */
@Transactional
@RestController
@RequestMapping("interface-info")
public class InterfaceInfoController {

    @Autowired
    private InterfaceInfoDao interfaceInfoDao;

    @Autowired
    private DataSourceInfoDao dataSourceInfoDao;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostMapping("/save")
    private Object save(@RequestBody InterfaceInfo interfaceInfo) {
        DataSourceInfo datasource = dataSourceInfoDao.findById(interfaceInfo.getDataSourceId()).orElseThrow(() -> new BizException("数据源不存在"));
        AssertUtils.notNull(datasource, "数据源不存在");
        AssertUtils.notBlank(interfaceInfo.getName(), "接口名称不能为空");
        InterfaceInfo info = interfaceInfoDao.findByNameAndDataSourceId(interfaceInfo.getName(), interfaceInfo.getDataSourceId());
        AssertUtils.isTrue((interfaceInfo.getId() == null && info == null) ||
                        (interfaceInfo.getId() != null && Objects.equals(interfaceInfo.getId(), info.getId())),
                "接口名称不能重复");
        if (interfaceInfo.getId() == null) {
            String code = "QUERY_" +
                    DateUtil.format(new Date(), "yyyyMMdd") +
                    String.format("%6d", RandomUtil.randomInt(1, 1000000)).replace(" ", "0");
            interfaceInfo.setCode(code);
        }
        return interfaceInfoDao.save(interfaceInfo);
    }

    @PostMapping("/deleteById")
    private Object deleteById(@RequestBody IdDto dto) {
        interfaceInfoDao.deleteById(dto.getId());
        return true;
    }

    @PostMapping("/stop")
    private Object stop(@RequestBody IdDto dto) {
        interfaceInfoDao.findById(dto.getId()).ifPresent(interfaceInfo -> {
            interfaceInfo.setStatus(Objects.equals(interfaceInfo.getStatus(), 1) ? 2 : 1);
            interfaceInfoDao.save(interfaceInfo);
        });
        return true;
    }

    @PostMapping("/share")
    private Object share(@RequestBody IdDto dto) {
        interfaceInfoDao.findById(dto.getId()).ifPresent(interfaceInfo -> {
            interfaceInfo.setIsShare(Objects.equals(interfaceInfo.getIsShare(), 1) ? 0 : 1);
            interfaceInfoDao.save(interfaceInfo);
        });
        return true;
    }

    @PostMapping("/send")
    private Object send(@RequestBody SendDto dto) {
        InterfaceInfo interfaceInfo = interfaceInfoDao.findById(dto.getId()).orElseThrow(() -> new BizException("接口不存在"));
        DataSourceInfo dataSourceInfo = dataSourceInfoDao.findById(interfaceInfo.getDataSourceId()).orElseThrow(() -> new BizException("数据源不存在"));
        String sql = interfaceInfo.getSql();
        List<Map<String, Object>> data = new ArrayList<>();
        try {
            Connection conn = DbUtils.getConn(dataSourceInfo);
            data = DbUtils.query(conn, sql, dto.getParam());
            DbUtils.close(conn);
        } catch (SQLException | ClassNotFoundException ignored) {

        }
        return data;
    }

    @PostMapping("/sendTest")
    private Object sendTest(@RequestBody SendTestDto dto) {
        DataSourceInfo dataSourceInfo = dataSourceInfoDao.findById(dto.getDatasourceId()).orElseThrow(() -> new BizException("数据源不存在"));
        String sql = dto.getSql();
        try {
            Connection conn = DbUtils.getConn(dataSourceInfo);
            DbUtils.query(conn, sql, dto.getParam());
            DbUtils.close(conn);
        } catch (SQLException | ClassNotFoundException e) {
            return false;
        }
        return true;
    }

    @PostMapping("/findById")
    private Object findById(@RequestBody IdDto dto) {
        return interfaceInfoDao.findById(dto.getId());
    }

    @PostMapping("/findPage")
    private Object findPage(@RequestBody QueryPage<InterfaceInfo> queryPage) {
        Pageable pageable = PageRequest.of(queryPage.getPageNum() - 1, queryPage.getPageSize(),
                Sort.by(Sort.Direction.DESC, "id"));
        InterfaceInfo query = queryPage.getQueryModel();
        query.setCount(null);
        query.setStatus(null);
        query.setIsShare(null);
        ExampleMatcher matching = ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
        return new PageResult<>(interfaceInfoDao.findAll(Example.of(query, matching), pageable));
    }
}
